﻿using System.Linq;
using System.Text;
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace TheGame
{
    //Gestisce grafica ed effetti sonori di un Mudokon
    public class Mudokon : Character
    {
        #region VARS
        SoundEffect Sound_PASS;
        SoundEffect Sound_TURN;
        SoundEffect Sound_JUMP;
        SoundEffect Sound_RUNSTOP;
        SoundEffect Sound_SNEAK;
        SoundEffect Sound_IMPACT;
        SoundEffect Sound_HELLO;
        SoundEffect Sound_OK;
        SoundEffect Sound_ENTERPORTAL;


        public Animation PASS_1;
        public Animation PASS_2;
        public Animation PASS_3;

        public Animation STOP;

        public Animation WAIT;
        public Animation HELLO;
        public Animation OK;

        public Animation TURN;

        public Animation SNEAK_1;
        public Animation SNEAK_2;
        public Animation SNEAK_3;
        public Animation SNEAKsTOP;

        public Animation RUN_1;
        public Animation RUN_2;
        public Animation RUN_3;
        public Animation RUN_4;
        public Animation RUN_5;
        public Animation RUNsTOP_1;
        public Animation RUNsTOP_2;
        public Animation RUNJUMP1;
        public Animation RUNJUMP2;
        public Animation RUNJUMP3;
        public Animation RUNJUMP4;

        public Animation JUMP_1;
        public Animation JUMP_2;
        public Animation JUMP_3;
        public Animation JUMP_4;


        public Animation WAITcROUCH;
        public Animation TURNdOWN;
        public Animation CROUCH;
        public Animation STANDUP;

        public Animation DIE;

        public Animation GODOWN;
        public Animation PLANE;

        public Animation CLEANUP;
        public Animation RESTUP;
        public Animation CLEANUPSTOPLEFT;
        public Animation CLEANUPSTOPRIGHT;
        public Animation CLEANDOWN;

        public Animation HOISTUP;
        public Animation HOISTDOWN;

        public Animation JUMPUP;
        public Animation JUMPDOWN;

        public Animation KO;
        public Animation GETUP;

        public Animation animTODO;
        Texture2D Mudokon_BBOX_PNG;
        public string state; 
        #endregion

        public Mudokon(Game1 game,string state,Point position)
        {
            this.game = game;

            ///////////////////////////////////////////////////

            Sound_PASS = game.MudokonFactory.Sound_PASS;
            Sound_TURN = game.MudokonFactory.Sound_TURN;
            Sound_JUMP = game.MudokonFactory.Sound_JUMP;
            Sound_RUNSTOP = game.MudokonFactory.Sound_RUNSTOP;
            Sound_SNEAK = game.MudokonFactory.Sound_SNEAK;
            Sound_IMPACT = game.MudokonFactory.Sound_IMPACT;
            Sound_HELLO = game.MudokonFactory.Sound_HELLO;
            Sound_OK = game.MudokonFactory.Sound_OK;
            Sound_ENTERPORTAL = game.MudokonFactory.Sound_ENTERPORTAL;

            ///////////////////////////////////////////////////


            WAIT = new Animation(game.MudokonFactory.Wait_R, game.MudokonFactory.Wait_L, 1000 / 6, 6, "WAIT", 0, 0, -1, 15, 15);
            TURN = new Animation(game.MudokonFactory.Turn_L, game.MudokonFactory.Turn_R, AnimateRate, 12, "TURN", new Sound(Sound_TURN, 2, 0.05f), 0, 0, -1, 10, 10);

            STOP = new Animation(game.MudokonFactory.Stop_R, game.MudokonFactory.Stop_L, AnimateRate, 4, "STOP", new Sound(Sound_PASS, 4), 0, 0, -1, 43, 43);
            PASS_1 = new Animation(game.MudokonFactory.Walk_1PASS_R, game.MudokonFactory.Walk_1PASS_L, AnimateRate, 7, "PASS_1", new Sound(Sound_PASS, 4), 1, 0, 6, 0, 43);
            PASS_2 = new Animation(game.MudokonFactory.Walk_2PASS_R, game.MudokonFactory.Walk_2PASS_L, AnimateRate, 9, "PASS_2", new Sound(Sound_PASS, 6), 1, 0, 8, 43, 86);
            PASS_3 = new Animation(game.MudokonFactory.Walk_3PASS_R, game.MudokonFactory.Walk_3PASS_L, AnimateRate, 9, "PASS_3", new Sound(Sound_PASS, 6), 1, 0, 8, 86, 129);

            JUMP_1 = new Animation(game.MudokonFactory.Jump1_R, game.MudokonFactory.Jump1_L, AnimateRate, 10, "JUMP_1", 1, 0, 3, 18, 61);
            JUMP_2 = new Animation(game.MudokonFactory.Jump2_R, game.MudokonFactory.Jump2_L, AnimateRate, 3, "JUMP_2", 1, 0, 3, 61, 104);
            JUMP_3 = new Animation(game.MudokonFactory.Jump3_R, game.MudokonFactory.Jump3_L, AnimateRate, 3, "JUMP_3", 1, 0, 3, 104, 147);
            JUMP_4 = new Animation(game.MudokonFactory.Jump4_R, game.MudokonFactory.Jump4_L, AnimateRate, 6, "JUMP_4", new Sound(Sound_JUMP, 1), 0, 0, -1, 147, 147);

            SNEAKsTOP = new Animation(game.MudokonFactory.SneakStop_R, game.MudokonFactory.SneakStop_L, AnimateRate, 4, "SNEAKsTOP", 0, 0, -1, 53, 53);
            SNEAK_1 = new Animation(game.MudokonFactory.Sneak1_R, game.MudokonFactory.Sneak1_L, AnimateRate, 6, "SNEAK_1", new Sound(Sound_SNEAK, 3), 1, 0, 5, 10, 53);
            SNEAK_2 = new Animation(game.MudokonFactory.Sneak2_R, game.MudokonFactory.Sneak2_L, AnimateRate, 10, "SNEAK_2", new Sound(Sound_SNEAK, 7), 1, 0, 9, 53, 96);
            SNEAK_3 = new Animation(game.MudokonFactory.Sneak3_R, game.MudokonFactory.Sneak3_L, AnimateRate, 10, "SNEAK_3", new Sound(Sound_SNEAK, 7), 1, 0, 9, 96, 139);

            RUN_1 = new Animation(game.MudokonFactory.Run1_R, game.MudokonFactory.Run1_L, AnimateRate, 4, "RUN_1", 2, 0, 3, 35, 35);
            RUN_2 = new Animation(game.MudokonFactory.Run2_R, game.MudokonFactory.Run2_L, AnimateRate, 2, "RUN_2", new Sound(Sound_PASS, 2), 2, 0, 4, 35, 78);
            RUN_3 = new Animation(game.MudokonFactory.Run3_R, game.MudokonFactory.Run3_L, AnimateRate, 3, "RUN_3", 2, 0, 9, 78, 121);
            RUN_4 = new Animation(game.MudokonFactory.Run4_R, game.MudokonFactory.Run4_L, AnimateRate, 5, "RUN_4", new Sound(Sound_PASS, 2), 2, 0, 9, 121, 164);
            RUN_5 = new Animation(game.MudokonFactory.Run5_R, game.MudokonFactory.Run5_L, AnimateRate, 6, "RUN_5", 2, 0, 9, 164, 207);
            
            RUNsTOP_1 = new Animation(game.MudokonFactory.RunStop1_R, game.MudokonFactory.RunStop1_L, AnimateRate, 8, "RUNSTOP_1", new Sound(Sound_RUNSTOP, 3), 1, 0, 7, 121, 164);
            RUNsTOP_2 = new Animation(game.MudokonFactory.RunStop2_R, game.MudokonFactory.RunStop2_L, AnimateRate, 8, "RUNSTOP_2", 1, 0, 7, 164, 207);
            
            RUNJUMP1 = new Animation(game.MudokonFactory.RunJump1_R, game.MudokonFactory.RunJump1_L, AnimateRate, 2, "RUNJUMP1", 1, 0, 1, 0, 43, 0, 0);
            RUNJUMP2 = new Animation(game.MudokonFactory.RunJump2_R, game.MudokonFactory.RunJump2_L, AnimateRate, 5, "RUNJUMP2", 1, 0, 7, 43, 86, 0, 50);
            RUNJUMP3 = new Animation(game.MudokonFactory.RunJump3_R, game.MudokonFactory.RunJump3_L, AnimateRate, 4, "RUNJUMP3",new Sound(Sound_ENTERPORTAL, 3), 1, 0, 7, 86, 129, 50, 50);
            RUNJUMP4 = new Animation(game.MudokonFactory.RunJump4_R, game.MudokonFactory.RunJump4_L, AnimateRate, 5, "RUNJUMP4", 1, 0, 7, 129, 172, 50, 0);

            WAITcROUCH = new Animation(game.MudokonFactory.WaitCrouch_R, game.MudokonFactory.WaitCrouch_L, 1000 / 6, 6, "WAITcROUCH", 0, 0, -1, 10, 10);
            TURNdOWN = new Animation(game.MudokonFactory.TurnDown_L, game.MudokonFactory.TurnDown_R, AnimateRate, 8, "TURNdOWN", new Sound(Sound_TURN, 2, 0.05f), 0, 0, -1, 10, 10);
            CROUCH = new Animation(game.MudokonFactory.Crouch_R, game.MudokonFactory.Crouch_L, AnimateRate, 9, "CROUCH", 0, 0, -1, 10, 10);
            STANDUP = new Animation(game.MudokonFactory.StandUp_R, game.MudokonFactory.StandUp_L, AnimateRate, 9, "STANDUP", 0, 0, -1, 10, 10);

            HELLO = new Animation(game.MudokonFactory.Wait_R, game.MudokonFactory.Wait_L, 1000 / 6, 6, "HELLO", new Sound(Sound_HELLO, 1), 0, 0, -1, 15, 15);
            OK = new Animation(game.MudokonFactory.Wait_R, game.MudokonFactory.Wait_L, 1000 / 6, 6, "OK", new Sound(Sound_OK, 1), 0, 0, -1, 15, 15);

            DIE = new Animation(game.MudokonFactory.Die_R, game.MudokonFactory.Die_L, AnimateRate, 28, "DIE", 0, 0, -1, 50, 50);
            //DOWNPLANE = new Animation(game.MudokonFactory.DownPlane_R, game.MudokonFactory.DownPlane_L, AnimateRate, 21, "DOWNPLANE", new Sound(Sound_IMPACT, 14), 0, 0, -1, 47, 90, 200, 0);
            GODOWN = new Animation(game.MudokonFactory.GoDown_R, game.MudokonFactory.GoDown_L, AnimateRate, 9, "GODOWN", 1, -2, 5, 12, 55, 200, 50);
            PLANE = new Animation(game.MudokonFactory.Plane_R, game.MudokonFactory.Plane_L, AnimateRate, 12, "PLANE", new Sound(Sound_IMPACT, 3), 1, 0, 2, 55, 98, 50, 0);

            CLEANUP = new Animation(game.MudokonFactory.CleanUp, game.MudokonFactory.CleanUp, 1000 / 10, 10, "CLEANUP", 0, 0, -1, 15, 15);
            RESTUP = new Animation(game.MudokonFactory.RestUp, game.MudokonFactory.RestUp, 1000 / 6, 6, "RESTUP", 0, 0, -1, 15, 15);
            CLEANUPSTOPLEFT = new Animation(game.MudokonFactory.CleanUpStop_L, game.MudokonFactory.CleanUpStop_L, 1000 / 30, 17, "CLEANUPSTOPLEFT", 0, 0, -1, 15, 15);
            CLEANUPSTOPRIGHT= new Animation(game.MudokonFactory.CleanUpStop_R, game.MudokonFactory.CleanUpStop_R, 1000 / 30, 17, "CLEANUPSTOPRIGHT", 0, 0, -1, 15, 15);
            CLEANDOWN = new Animation(game.MudokonFactory.CleanDown_R, game.MudokonFactory.CleanDown_L, 1000 / 30, 11, "CLEANDOWN", 0, 0, -1, 10, 10);


            HOISTUP = new Animation(game.MudokonFactory.HoistUp_R, game.MudokonFactory.HoistUp_L, AnimateRate, 23, "HOISTUP", 0, 0, -1, 15, 15, 0, 150);
            HOISTDOWN = new Animation(game.MudokonFactory.HoistDown_R, game.MudokonFactory.HoistDown_L, AnimateRate, 23, "HOISTDOWN", 0, 0, -1, 15, 15, 150, 0);

            JUMPDOWN = new Animation(game.MudokonFactory.JumpDown_R, game.MudokonFactory.JumpDown_L, AnimateRate, 18, "JUMOdOWN", new Sound(Sound_JUMP, 7), 0, -1, 10, 15, 15, 50, 0);
            JUMPUP = new Animation(game.MudokonFactory.JumpUp_R, game.MudokonFactory.JumpUp_L, AnimateRate, 14, "JUMPuP", new Sound(Sound_PASS, 13), 0, 1, 13, 15, 15, 0, 50);

            KO = new Animation(game.MudokonFactory.Ko_R, game.MudokonFactory.Ko_L, AnimateRate, 13, "KO", new Sound(Sound_IMPACT, 3), 0, 0, -1, 46, 46);
            GETUP = new Animation(game.MudokonFactory.GetUp_R, game.MudokonFactory.GetUp_L, AnimateRate, 13, "GETUP", 0, 0, -1, 46, 46);

            Direction = 1;
            color = Color.Yellow;
            AI = new MudokonAI(this, game, state);
            CurrentAnimation = AI.CURRENT_STATE.AnimsTODO[AI.CURRENT_STATE.CURRENT_ANIM];
            animTODO = CurrentAnimation;
            PrevAnimation = CurrentAnimation;
            DrawingRec = new Rectangle(position.X - 18, position.Y - CurrentAnimation.Sheet.Height + 5, CurrentAnimation.SpriteWidth, CurrentAnimation.SpriteHeight);//-18 + 215, 285
            boundingBox = new Rectangle(position.X, position.Y - boundingBox.Height, 44, 150);//42

            Mudokon_BBOX_PNG = game.Content.Load<Texture2D>("Sprite_Sheet\\Abe\\ABE_BBOX");
            this.state = state;
            

        }

        //Gestisce la spritesheet dell'animazione corrente.
        //Definisce quale frame della spritesheet deve essere disegnato.
        public void AnimateMudokon(Animation anim)
        {
            if (anim.CurrentFrame == 0)
            {
                PrevAnimation = CurrentAnimation;
                PrevAnimation.Reset();
                CurrentAnimation = anim;

                if (Direction == 1)
                {
                    DrawingRec.X = DrawingRec.X + (PrevAnimation.xEND - CurrentAnimation.xSTART);
                }
                else
                {
                    DrawingRec.X = DrawingRec.X + ((PrevAnimation.SpriteLWidth - PrevAnimation.xEND) - (CurrentAnimation.SpriteLWidth - CurrentAnimation.xSTART));
                }

                DrawingRec.Y = DrawingRec.Y - (PrevAnimation.yEND - CurrentAnimation.ySTART) + (PrevAnimation.SpriteHeight - CurrentAnimation.SpriteHeight);

                if (CurrentAnimation == TURN || CurrentAnimation == TURNdOWN)
                    Direction = Direction * -1;
                if (CurrentAnimation == CLEANUPSTOPLEFT)
                    Direction =  -1;
                if (CurrentAnimation == CLEANUPSTOPRIGHT)
                    Direction = 1;

                if (Direction == 1)
                {
                    anim.SpriteWidth = anim.SpriteRWidth;
                    anim.SpriteHeight = anim.SpriteRHeight;
                    anim.Sheet = anim.SheetR;
                }
                else
                {
                    anim.SpriteWidth = anim.SpriteLWidth;
                    anim.SpriteHeight = anim.SpriteLHeight;
                    anim.Sheet = anim.SheetL;
                }

                DrawingRec.Width = anim.SpriteWidth;
                DrawingRec.Height = anim.SpriteHeight;

                this.game.spriteCurrent = anim.Sheet;
            }

            if (anim.Time > anim.AnimateRate)
            {
                if (anim.CurrentFrame == 1)
                {
                    boundingBox.X += (anim.xEND - anim.xSTART) * Direction;
                    boundingBox.Y = DrawingRec.Bottom - (anim.yEND + boundingBox.Height);
                }
                anim.Time = 0f;
                if (anim.Effect != null && anim.CurrentFrame == anim.Effect.FrameToPlay)
                    anim.Effect.Play();

                if (anim.CurrentFrame == anim.FrameCount)
                {
                    anim.LastFrameDone = true;

                }
                else
                    anim.LastFrameDone = false;

                if (anim.CurrentFrame < anim.FrameCount)
                {
                    anim.SourceRect = new Rectangle(anim.CurrentFrame * anim.SpriteWidth, 0, anim.SpriteWidth, anim.SpriteHeight);
                    this.game.sourceRect = anim.SourceRect;
                    anim.Forward();
                }
            }
        }

        #region Attribute
        public Rectangle BoundigBox
        {
            get { return boundingBox; }
            set { boundingBox = value; }
        }

        public Texture2D MUDOKON_BBOX_PNG
        {
            get { return Mudokon_BBOX_PNG; }
        }

        public Animation getAnimbyName(string anim)
        {
            if (anim == PASS_1.Name)
                return PASS_1;
            if (anim == PASS_2.Name)
                return PASS_3;
            if (anim == PASS_3.Name)
                return PASS_3;
            if (anim == TURN.Name)
                return TURN;
            if (anim == "STOP_1" || anim == "STOP_2" || anim == "STOP_3")
                return STOP;
            if (anim == SNEAK_1.Name)
                return SNEAK_1;
            if (anim == SNEAK_2.Name)
                return SNEAK_2;
            if (anim == SNEAK_3.Name)
                return SNEAK_3;

            return WAIT;
        }
        #endregion

    }
}
